﻿
properties {
    $baseDirectory = resolve-path .
    $libDirectory = "$baseDirectory\lib"
    $toolsDirectory = "$baseDirectory\tools"
    $buildDirectory = "$baseDirectory\build"
    $distDirectory = "$buildDirectory\dist"
    $srcDirectory = "$baseDirectory\src"
    $solutionFilepath = "$srcDirectory\Actya.sln"
    $version = "0.3.0"
    $informationalVersion = "$version-beta"
    $global:config = "DEBUG"

    $nuGetPackageName = "Actya"
    $nuGetPackageDir = "$buildDirectory\NuGet"
    $nuSpecFileName = "Actya.nuspec"
}

include .\buildfunctions.ps1

task default -depends Build, IntegrationTests

task Verify40 {
	if( (ls "$env:windir\Microsoft.NET\Framework\v4.0*") -eq $null ) {
		throw "Building Actya requires .NET 4.0, which doesn't appear to be installed on this machine"
	}
}

task Clean {
    if (test-path $buildDirectory) {
        remove-item $buildDirectory -force -recurse 
    }
}

task AssemblyInfos -depends Verify40, Clean {
    $buildLabel = if ("$env:BUILD_NUMBER".length -gt 0) { "$env:BUILD_NUMBER" } else { "0" }

	$projectFiles = ls -path $base_dir -include *.csproj -recurse |
		Where { $_ -notmatch [regex]::Escape($libDirectory) } |
		Where { $_ -notmatch [regex]::Escape($toolsDirectory) }

	foreach($projectFile in $projectFiles) {

		$projectDir = [System.IO.Path]::GetDirectoryName($projectFile)
		$projectName = [System.IO.Path]::GetFileName($projectDir)
		$asmInfo = [System.IO.Path]::Combine($projectDir, [System.IO.Path]::Combine("Properties", "AssemblyInfo.cs"))

		Generate-Assembly-Info `
			-file $asmInfo `
			-title "$projectName $version.0" `
			-description "" `
			-company "Actya" `
			-product "Actya $version" `
			-version "$version" `
			-fileversion "$version.$buildlabel" `
			-informationalversion "$informationalVersion" `
			-copyright "Copyright © Actya / Martijn Boland 2011-2012" `
			-clsCompliant "true"
	}
}

task Build -depends AssemblyInfos, Verify40, Clean {
	Write-Host "Building Actya in $config configuration"

	$v4_net_version = (ls "$env:windir\Microsoft.NET\Framework\v4.0*").Name
    exec { &"C:\Windows\Microsoft.NET\Framework\$v4_net_version\MSBuild.exe" $solutionFilepath /p:Configuration=$config /v:Minimal /p:OutDir="$buildDirectory\" }

    Write-Host "Cleaning obj dirs after build."

    $objDirs = ls -path $base_dir -include *obj* -recurse |
		Where { $_ -notmatch [regex]::Escape($libDirectory) } |
		Where { $_ -notmatch [regex]::Escape($toolsDirectory) } |
		Where { $_.psIsContainer -eq $true }
	foreach($objDir in $objDirs) {
		rm -Force -Recurse "$objDir"
	}
}

task IntegrationTests -depends Build {
	$nunit_console_path = Get-Tool-Path-From-NuGet-Package $baseDirectory "nunit-console.exe"
	if ($nunit_console_path -eq $null) {
		throw "nunit-console.exe could not be found in the nuget packages"
	}
	Write-Host "Using $nunit_console_path as test runner for integration tests"
	$resultsFilepath = "$buildDirectory\Actya.IntegrationTests.results.xml"
    exec { & $nunit_console_path /nologo /xml="$resultsFilePath" "$($buildDirectory)\Actya.IntegrationTests.dll" }
    Write-Output "##teamcity[importData type='nunit' path='$resultsFilepath']"
}

task Merge {
	$librariesToMerge = @( `
		"Actya.Web.dll", `
		"Actya.Core.dll", `
		"Autofac.dll", `
		"Autofac.Configuration.dll", `
		"Autofac.Integration.Mvc.dll", `
		"BouncyCastle.Crypto.dll", `
		"Castle.Core.dll", `
		"ICSharpCode.NRefactory.dll", `
		"Lucene.Net.dll", `
		"Microsoft.Web.Infrastructure.dll", `
		"MvcPaging.dll", `
		"Newtonsoft.Json.dll", `
		"NLog.dll", `
		"Raven.Abstractions.dll", `
		"Raven.Client.Embedded.dll", `
		"Raven.Client.Lightweight.dll", `
		"Raven.Database.dll", `
		"Raven.Munin.dll", `
		"Raven.Storage.Managed.dll", `
		"WebActivator.dll")

	$old = pwd
	cd $buildDirectory

	remove-item "Actya.dll" -erroraction SilentlyContinue
    
    $v4_net_version = (ls "$env:windir\Microsoft.NET\Framework\v4.0*").Name 
     
	& $toolsDirectory\ILMerge.exe /out:"Actya.dll" /t:library /log:"Actya.merge.log" `
		/targetplatform:"v4,$env:windir\Microsoft.NET\Framework\$v4_net_version" `
		$librariesToMerge
                          
	if ($lastExitCode -ne 0) {
		throw “Error: Failed to merge assemblies!”
	}
	cd $old
}

task Buildserver {
	if ($env:TEAMCITY_VERSION) {
		# When PowerShell is started through TeamCity's Command Runner, the standard
		# output will be wrapped at column 80 (a default). This has a negative impact
		# on service messages, as TeamCity quite naturally fails parsing a wrapped
		# message. The solution is to set a new, much wider output width. It will
		# only be set if TEAMCITY_VERSION exists, i.e., if started by TeamCity.
		$host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(8192,50)
	}
}

task SetReleaseConfig {
	$global:config = "RELEASE"
}

task NuGet -depends Build {
	mkdir $nuGetPackageDir
    cp "$nuSpecFileName" "$nuGetPackageDir"

    mkdir "$nuGetPackageDir\lib\4.0"
	mkdir "$nuGetPackageDir\content\CmsContent"
	mkdir "$nuGetPackageDir\content\CmsContent\Themes"
	mkdir "$nuGetPackageDir\content\CmsContent\Upload"
	mkdir "$nuGetPackageDir\content\CmsContent\Plugins"
	mkdir "$nuGetPackageDir\content\CmsContent\Plugins\Actya.Plugins.Hello"
	mkdir "$nuGetPackageDir\content\CmsContent\Plugins\Actya.Plugins.Hello\bin"
	mkdir "$nuGetPackageDir\content\CmsContent\_tmb"

    cp "$buildDirectory\Actya.Core.dll" "$nuGetPackageDir\lib\4.0"
    cp "$buildDirectory\Actya.Web.dll" "$nuGetPackageDir\lib\4.0"
    cp "$buildDirectory\_PublishedWebsites\Actya.Web\CmsContent\Themes\Admin" "$nuGetPackageDir\content\CmsContent\Themes" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Web\CmsContent\Themes\Default" "$nuGetPackageDir\content\CmsContent\Themes" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Web\CmsContent\Themes\MvcApplication" "$nuGetPackageDir\content\CmsContent\Themes" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\plugin.json" "$nuGetPackageDir\content\CmsContent\Plugins\Actya.Plugins.Hello" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\bin\Actya.Plugins.Hello.dll" "$nuGetPackageDir\content\CmsContent\Plugins\Actya.Plugins.Hello\bin" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\Views" "$nuGetPackageDir\content\CmsContent\Plugins\Actya.Plugins.Hello" -Recurse

    $Spec = [xml](get-content "$nuGetPackageDir\$nuSpecFileName")
    $Spec.package.metadata.version = ([string]$Spec.package.metadata.version).Replace("{version}", $informationalversion)
    $Spec.Save("$nuGetPackageDir\$nuSpecFileName")

    exec { & $toolsDirectory\NuGet.exe pack "$nuGetPackageDir\$nuSpecFileName" -OutputDirectory "$nuGetPackageDir" }

    if ($lastExitCode -ne 0) {
		throw “Error: Failed to create NuGet package.”
	}
}

task PackageInit {
	Write-Host "Creating directory for packaging: $distDirectory"

	mkdir $distDirectory
}

task PackageSource -depends PackageInit {
	Write-Host "Copying source file for packaging"

	$sourcesDir = "$distDirectory\sources"
	mkdir "$sourcesDir"
	mkdir "$sourcesDir\src"

	cp "$baseDirectory\*.*" "$sourcesDir" -Exclude @(".hg")
	cp "$solutionFilepath" "$sourcesDir\src"
	cp -Recurse "$libDirectory" "$sourcesDir"
	cp -Recurse "$toolsDirectory" "$sourcesDir"

	Get-ChildItem -Recurse "$srcDirectory" -Exclude *.user | 
		Where-Object { $_.FullName -notmatch '\\(bin|obj|App_Data|Upload|Packages|_ReSharper.Actya|Sample\w+\\CmsContent\\Themes)($|\\)' } | 
		Copy-Item -Destination {Join-Path "$sourcesDir\src" $_.FullName.Substring($srcDirectory.length)}

	$file = "$distDirectory\Actya-$informationalVersion-src.zip"

	Write-Host "Creating source package $file"

	$old = pwd
	
	cd $sourcesDir

	exec { 
		& $toolsDirectory\7za.exe a -tzip -r `
			$file `
			src\* `
			tools\* `
			lib\* `
			*.*
	}

	if ($lastExitCode -ne 0) {
		throw “Error: Failed to create source package.”
	}

	cd $old
}

task PackageBin -depends PackageInit {
	Write-Host "Copying missing files for binary package"

	$publishDir = "$buildDirectory\_PublishedWebsites\Actya.Web"
	rm "$publishDir\*.config"
	cp "$srcDirectory\Actya.Web\web.config" "$publishDir"
	cp "$baseDirectory\README.md" "$publishDir"
	cp "$baseDirectory\*.txt" "$publishDir"
	cp -Force "$buildDirectory\Raven.*.*" "$publishDir\bin"
	mkdir -Force "$publishDir\App_Data\CMS"
	mkdir -Force "$publishDir\CmsContent\Upload"
	mkdir -Force "$publishDir\CmsContent\_tmb"
	mkdir -Force "$publishDir\CmsContent\Plugins\Actya.Plugins.Hello"
	mkdir -Force "$publishDir\CmsContent\Plugins\Actya.Plugins.Hello\bin"
	cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\plugin.json" "$publishDir\CmsContent\Plugins\Actya.Plugins.Hello" -Recurse
	cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\bin\Actya.Plugins.Hello.dll" "$publishDir\CmsContent\Plugins\Actya.Plugins.Hello\bin" -Recurse
    cp "$buildDirectory\_PublishedWebsites\Actya.Plugins.Hello\Views" "$publishDir\CmsContent\Plugins\Actya.Plugins.Hello" -Recurse

	$file = "$distDirectory\Actya-$informationalVersion-bin.zip"
	
	Write-Host "Creating binary package $file"

	$old = pwd
	
	cd $publishDir

	exec { 
		& $toolsDirectory\7za.exe a -tzip -r `
			$file `
			*
	}

	if ($lastExitCode -ne 0) {
		throw “Error: Failed to create binary package.”
	}

	cd $old
}

task CI -depends Buildserver, IntegrationTests

task Daily -depends Buildserver, IntegrationTests, NuGet 

task Release -depends SetReleaseConfig, Buildserver, IntegrationTests, NuGet, PackageSource, PackageBin {
	
}
